﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;


public class IniFile
{
    Dictionary<string,Dictionary<string,string>> sectionData=new Dictionary<string,Dictionary<string,string>>();
    string filename;
    string encoding;

    	public void load(string filename,string encoding=null)
    	{
            try
            {
                this.filename = filename;
                this.encoding = encoding;
                String[] lines = File.ReadAllLines(filename, encoding==null?Encoding.Default:Encoding.GetEncoding(encoding));
                string section = "";
                foreach (string l in lines)
                {
                    string line = l.Trim();
                    int len = line.Length;
                    if (!String.IsNullOrWhiteSpace(line) && line[0] != '#') //跳过空行和注释
                    {
                        if (len > 2 && line[0] == '[' && line[len - 1] == ']')
                            section = line.Substring(1, len - 2).Trim(); //得到section名称
                        else
                        {
                            Dictionary<string, string> data;
                            if (sectionData.ContainsKey(section))
                                data = sectionData[section];
                            else
                            {
                                data = new Dictionary<string, string>();
                                sectionData.Add(section, data);
                            }
                            int idx = line.IndexOf('=');
                            if (idx >= 0)
                            {

                                data.Add(line.Substring(0, idx).Trim(), line.Substring(idx + 1).Trim());
                            }
                            else  //没有=，全部当作key
                                data.Add(line, null);
                        }
                    }
                }
            }
            catch(Exception e)
            {

            }
    	}
    	
    	public IniFile(string filename,string encoding=null)
    	{
    		load(filename,encoding);
    	}
    	
    	public bool containsSection(string section)
    	{
    		return sectionData.ContainsKey(section);
    	}
    	
    	public bool containsKey(string section,string key)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                return data != null && data.ContainsKey(key);
            }
            return false;
    	}

    	public string get(string section,string key,string def=null)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                    return data[key];
            }
    		return def;
    	}
    	
    	public byte getByte(string section,string key,byte def=0)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return byte.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public bool getBoolean(string section,string key,bool def=false)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null)
                {
                    string ret = data[key];
                    if (ret != null && (String.Compare(ret, "true", true) == 0 || String.Compare(ret, "yes", true) == 0 || ret == "1"))
                        return true;
                }
            }
    		return def;
    	}
    	
    	public int getInt(string section,string key,int def=0)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return int.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public short getShort(string section,string key,short def=0)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return short.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public long getLong(string section,string key,long def=0L)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return long.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public float getFloat(string section,string key,float def=0f)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return float.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public double getDouble(string section,string key,double def=0d)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null && data.ContainsKey(key))
                {
                    return double.Parse(data[key]);
                }
            }
    		return def;
    	}
    	
    	public HashSet<string> getSections()
    	{
            return new HashSet<string>(sectionData.Keys);
    	}
    	
    	public HashSet<string> getSectionKeys(string section)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null)
                    return new HashSet<string>(data.Keys);
            }
    		return null;
    	}
    	
    	public List<string> getSectionValues(string section)
    	{
            if (sectionData.ContainsKey(section))
            {
                Dictionary<string, string> data = sectionData[section];
                if (data != null)
                    return new List<string>(data.Values);
            }
    		return null;
    	}
    	
    	public Dictionary<string,string> getSectionDict(string section)
    	{
            if (sectionData.ContainsKey(section))
                return sectionData[section];
    		return null;
    	}
    	
    	public void set(string section,string key,string value)
    	{
            Dictionary<string, string> data = null;
            if (sectionData.ContainsKey(section))
                data = sectionData[section];
            if(data==null)
            {
                data = new Dictionary<string, string>();
                sectionData[section]=data;
            }
            data[key]=value;
    	}

        public void set(string section,string key,object value)
        {
            set(section, key, value.ToString());
        }

        public void save()
        {
            if (!String.IsNullOrEmpty(filename))
                saveFile(filename, encoding);
        }

        public bool renameSection(string section,string new_section)
        {
            if (section != new_section && sectionData.ContainsKey(section) && !sectionData.ContainsKey(new_section))
            {
                sectionData[new_section] = sectionData[section];
                sectionData[section]=null;
                return true;
            }
            return false;
        }

        public bool removeSection(string section)
        {
            if (sectionData.ContainsKey(section))
            {
                sectionData[section] = null;
                return true;
            }
            return false;
        }

        public void saveFile(string filename, string encoding=null)
    	{
    		StringBuilder sb=new StringBuilder();

            Dictionary<string,string> data=null;
    		foreach(string section in sectionData.Keys)
    		if(section!=null)
    		{

    			sb.Append('[');
    			if(section!=null)
    				sb.Append(section);
    			sb.AppendLine("]");

    			data=sectionData[section];
    			foreach(string key in data.Keys)
    			{
    				if(key!=null) sb.Append(key);
    				sb.Append('=');
    				string value=data[key];
    				if(value!=null)
                        sb.Append(value);
                    sb.AppendLine();
    			}
                sb.AppendLine();
    		}
            File.WriteAllText(filename, sb.ToString(), encoding == null ? Encoding.Default : Encoding.GetEncoding(encoding));
    	}
}
